package com.pipi.sso.core.service.impl;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.pipi.sso.core.exception.DormServiceException;
import com.pipi.sso.core.service.DormitoryRoomService;
import com.pipi.sso.core.enums.CommonStatusEnum;
import com.pipi.sso.core.enums.DormErrorCodeEnum;
import com.pipi.sso.core.model.DormitoryRoomBO;
import com.pipi.sso.core.util.BeanUtils;
import com.pipi.sso.dao.manager.DormitoryAllocationManager;
import com.pipi.sso.dao.manager.DormitoryBuildingManager;
import com.pipi.sso.dao.manager.DormitoryRoomManager;
import com.pipi.sso.dao.model.DormitoryAllocationDO;
import com.pipi.sso.dao.model.DormitoryBuildingDO;
import com.pipi.sso.dao.model.DormitoryRoomDO;
import com.pipi.sso.dao.query.DormitoryAllocationQuery;
import com.pipi.sso.dao.query.DormitoryRoomQuery;
import com.pipi.sso.dao.support.PageResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * All rights Reserved, Designed By www.maihaoche.com
 *
 * @Package com.pipi.sso.core.service.impl
 * @date: 2019/4/14 5:43 PM
 * @Copyright: 2017-2020 www.maihaoche.com Inc. All rights reserved.
 */
@Service
@Slf4j
public class DormitoryRoomServiceImpl implements DormitoryRoomService {

    @Resource
    private DormitoryRoomManager dormitoryRoomManager;

    @Resource
    private DormitoryBuildingManager dormitoryBuildingManager;

    @Resource
    private DormitoryAllocationManager dormitoryAllocationManager;

    @Override
    public PageResult<DormitoryRoomBO> queryByPaged(DormitoryRoomBO dormitoryRoomBO) {
        DormitoryRoomQuery query = buildQuery(dormitoryRoomBO);
        query.setPageNo(dormitoryRoomBO.getPage());
        query.setPageSize(dormitoryRoomBO.getLimit());
        try {
            PageResult<DormitoryRoomDO> pageResult = dormitoryRoomManager.selectByQueryWithPage(query);
            if (CollectionUtils.isEmpty(pageResult.getResult())) {
                return PageResult.createPageResult();
            }
            List<DormitoryRoomBO> dormitoryRoomBOS = buildBOs(pageResult.getResult());
            return PageResult.createPageResult(dormitoryRoomBOS, pageResult.getPageInfo());
        } catch (Exception e) {
            log.error("查询宿舍信息失败! dormitoryRoomBO is {}", JSON.toJSONString(dormitoryRoomBO), e);
            throw new DormServiceException(DormErrorCodeEnum.QUERY_DORMITORY_ROOT_FAIL);
        }
    }

    @Override
    public List<DormitoryRoomBO> queryNoPaged(DormitoryRoomBO dormitoryRoomBO) {
        DormitoryRoomQuery query = buildQuery(dormitoryRoomBO);
        try {
            List<DormitoryRoomDO> dormitoryRoomDOS = dormitoryRoomManager.selectByQuery(query);
            if (CollectionUtils.isEmpty(dormitoryRoomDOS)) {
                return Lists.newArrayList();
            }
            return buildBOs(dormitoryRoomDOS);
        } catch (Exception e) {
            log.error("查询宿舍信息失败! dormitoryRoomBO is {}", JSON.toJSONString(dormitoryRoomBO), e);
            throw new DormServiceException(DormErrorCodeEnum.QUERY_DORMITORY_ROOT_FAIL);
        }
    }

    @Override
    public void addDormitoryRoom(DormitoryRoomBO dormitoryRoomBO) {
        try {
            DormitoryRoomQuery query = buildQuery(dormitoryRoomBO);
            List<DormitoryRoomDO> dormitoryRoomDOS = dormitoryRoomManager.selectByQuery(query);
            if (CollectionUtils.isNotEmpty(dormitoryRoomDOS)) {
                log.error("同一宿舍不可重复添加！dormitoryRoomBO is {}",
                        JSON.toJSONString(dormitoryRoomBO));
                throw new DormServiceException(DormErrorCodeEnum.
                        ADD_DORMITORY_ROOM_FAIL.getErrCode(), "同一宿舍不可重复添加");
            }
            DormitoryBuildingDO dormitoryBuildingDO = dormitoryBuildingManager.
                    selectByPrimaryKey(dormitoryRoomBO.getBuildingId());

            DormitoryRoomDO dormitoryRoomDO = BeanUtils.createCloneBean
                    (dormitoryRoomBO, DormitoryRoomDO.class);
            dormitoryRoomDO.setBuildingNo(dormitoryBuildingDO.getBuildingNo());
            dormitoryRoomDO.setIsDeleted(CommonStatusEnum.NO.getCode());
            dormitoryRoomManager.insertSelective(dormitoryRoomDO);
        } catch (DormServiceException e) {
            throw e;
        } catch (Exception e) {
            log.error("添加宿舍失败! dormitoryRoomBO is {}", JSON.toJSONString(dormitoryRoomBO), e);
            throw new DormServiceException(DormErrorCodeEnum.ADD_DORMITORY_ROOM_FAIL);
        }
    }

    @Override
    public void updateDormitoryRoom(DormitoryRoomBO dormitoryRoomBO) {
        try {
            DormitoryRoomQuery query = new DormitoryRoomQuery();
            query.createCriteria().andDormitoryRoomIdNotEqualTo(dormitoryRoomBO.getDormitoryRoomId())
                    .andBuildingIdEqualTo(dormitoryRoomBO.getBuildingId())
                    .andRoomNoEqualTo(dormitoryRoomBO.getRoomNo())
                    .andIsDeletedEqualTo(CommonStatusEnum.NO.getCode());
            List<DormitoryRoomDO> dormitoryRoomDOS = dormitoryRoomManager.selectByQuery(query);
            if (CollectionUtils.isNotEmpty(dormitoryRoomDOS)) {
                log.error("新的宿舍信息已存在！dormitoryRoomBO is {}", JSON.toJSONString(dormitoryRoomBO));
                throw new DormServiceException(DormErrorCodeEnum.UPDATE_DORMITORY_ROOM_FAIL.getErrCode(), "新的宿舍信息已存在");
            }
            DormitoryRoomDO dormitoryRoomDO = BeanUtils.createCloneBean(dormitoryRoomBO, DormitoryRoomDO.class);
            dormitoryRoomManager.updateByPrimaryKeySelective(dormitoryRoomDO);
        } catch (DormServiceException e) {
            throw e;
        } catch (Exception e) {
            log.error("更新宿舍失败！dormitoryRoomBO is {}", JSON.toJSONString(dormitoryRoomBO), e);
            throw new DormServiceException(DormErrorCodeEnum.UPDATE_DORMITORY_ROOM_FAIL);
        }
    }

    @Override
    public void deleteDormitoryRoom(List<Long> dormitoryRoomIds) {
        try {
            DormitoryAllocationQuery dormitoryAllocationQuery = new DormitoryAllocationQuery();
            dormitoryAllocationQuery.createCriteria().andIsDeletedEqualTo(CommonStatusEnum.NO.getCode()).andDormitoryRoomIdIn(dormitoryRoomIds);
            List<DormitoryAllocationDO> dormitoryAllocationDOS = dormitoryAllocationManager.selectByQuery(dormitoryAllocationQuery);
            if (CollectionUtils.isNotEmpty(dormitoryAllocationDOS)) {
                log.error("有学生入住的宿舍不能删除！dormitoryRoomIds is {}", JSON.toJSONString(dormitoryRoomIds));
                throw new DormServiceException(DormErrorCodeEnum.DELETE_DORMITORY_ROOM_FAIL.getErrCode(), "有学生入住的宿舍不能删除");
            }
            DormitoryRoomQuery dormitoryRoomQuery = new DormitoryRoomQuery();
            dormitoryRoomQuery.createCriteria().andDormitoryRoomIdIn(dormitoryRoomIds);
            DormitoryRoomDO dormitoryRoomDO = new DormitoryRoomDO();
            dormitoryRoomDO.setIsDeleted(CommonStatusEnum.YES.getCode());
            dormitoryRoomManager.updateByQuerySelective(dormitoryRoomDO, dormitoryRoomQuery);
        } catch (DormServiceException e) {
            throw e;
        } catch (Exception e) {
            log.error("删除宿舍失败！dormitoryRoomIds is {}", JSON.toJSONString(dormitoryRoomIds));
            throw new DormServiceException(DormErrorCodeEnum.DELETE_DORMITORY_ROOM_FAIL);
        }
    }

    private DormitoryRoomQuery buildQuery(DormitoryRoomBO dormitoryRoomBO) {
        DormitoryRoomQuery query = new DormitoryRoomQuery();
        query.setOrderByClause("gmt_create desc");
        DormitoryRoomQuery.Criteria criteria = query.createCriteria().andIsDeletedEqualTo(CommonStatusEnum.NO.getCode());
        if (Objects.nonNull(dormitoryRoomBO)) {
            if (Objects.nonNull(dormitoryRoomBO.getDormitoryRoomId())) {
                criteria.andDormitoryRoomIdEqualTo(dormitoryRoomBO.getDormitoryRoomId());
            }
            if (Objects.nonNull(dormitoryRoomBO.getBuildingId())) {
                criteria.andBuildingIdEqualTo(dormitoryRoomBO.getBuildingId());
            }
            if (StringUtils.isNotBlank(dormitoryRoomBO.getRoomNo())) {
                criteria.andRoomNoEqualTo(dormitoryRoomBO.getRoomNo());
            }
            if (Objects.nonNull(dormitoryRoomBO.getGender())) {
                criteria.andGenderEqualTo(dormitoryRoomBO.getGender());
            }
        }
        return query;
    }


    private List<DormitoryRoomBO> buildBOs(List<DormitoryRoomDO> dormitoryRoomDOS) {
        if (CollectionUtils.isEmpty(dormitoryRoomDOS)) {
            return null;
        }
        return dormitoryRoomDOS.stream().map(this::buildBO).collect(Collectors.toList());
    }

    private DormitoryRoomBO buildBO(DormitoryRoomDO dormitoryRoomDO) {
        if (Objects.isNull(dormitoryRoomDO)) {
            return null;
        }
        DormitoryRoomBO dormitoryRoomBO = BeanUtils.createCloneBean(dormitoryRoomDO, DormitoryRoomBO.class);
        DormitoryAllocationQuery dormitoryAllocationQuery = new DormitoryAllocationQuery();
        dormitoryAllocationQuery.createCriteria().andIsDeletedEqualTo(CommonStatusEnum.NO.getCode()).andDormitoryRoomIdEqualTo(dormitoryRoomBO.getDormitoryRoomId());
        int count = dormitoryAllocationManager.countByQuery(dormitoryAllocationQuery);
        dormitoryRoomBO.setCheckNumber(count);
        dormitoryRoomBO.setGenderDesc(CommonStatusEnum.getGenderDescByCode(dormitoryRoomDO.getGender()));
        dormitoryRoomBO.setRoomName(dormitoryRoomBO.getBuildingNo() + "-" + dormitoryRoomBO.getRoomNo());
        return dormitoryRoomBO;
    }
}
